<template>
  <div id="NotesManagePage">
    <a-flex justify="space-between">
      <h2>笔记审阅</h2>
      <a-button type="primary" href="/addNote" target="_blank">+ 添加笔记</a-button>
    </a-flex>
    <div style="margin-bottom: 16px"></div>

    <a-form layout="inline" :model="searchParams" @finish="doSearch">
      <a-form-item label="关键词" name="searchText">
        <a-input
          v-model:value="searchParams.searchText"
          placeholder="从标题和内容搜索"
          allow-clear
        />
      </a-form-item>
      <a-form-item label="类型" name="category" style="margin-left: 60px">
        <a-select
          v-model:value="searchParams.categoryId"
          placeholder="请选择分类"
          style="width: 200px"
          allow-clear
        >
          <a-select-option v-for="category in categoryList" :key="category.id" :value="category.id">
            {{ category.categoryName }}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="审核状态" name="reviewStatus" style="margin-left: 60px">
        <a-select
          v-model:value="searchParams.reviewStatus"
          placeholder="请选择审核状态"
          style="width: 200px"
          allow-clear
          @change="doSearch"
          :defaultValue="1"
        >
          <a-select-option :value="0">无需审核</a-select-option>
          <a-select-option :value="1">待审核</a-select-option>
          <a-select-option :value="2">已通过</a-select-option>
          <a-select-option :value="3">已拒绝</a-select-option>
        </a-select>
      </a-form-item>
      <!--      <a-form-item label="标签" name="tags">
              <a-select
                v-model:value="searchParams.tags"
                mode="tags"
                placeholder="请输入标签"
                style="min-width: 180px"
                allow-clear
              />
            </a-form-item>-->
      <a-form-item>
        <a-button type="primary" html-type="submit">搜索</a-button>
      </a-form-item>
    </a-form>

    <div style="margin-bottom: 16px"></div>
    <a-table
      :columns="columns"
      :data-source="dataList"
      :pagination="pagination"
      @change="doTableChange"
      :scroll="{ x: 1500 }"
    >
      <template #bodyCell="{ column, record }">
        <!-- 标签 -->
        <template v-if="column.dataIndex === 'tagList'">
          <div class="tags-wrapper">
            <div class="tags-container">
              <a-tag v-for="tag in record.tagList || '[]'" :key="tag.id" class="tag-item">
                {{ tag.tagName }}
              </a-tag>
            </div>
          </div>
        </template>
        <template v-else-if="column.dataIndex === 'createTime'">
          {{ dayjs(record.createTime).format('YYYY-MM-DD HH:mm:ss') }}
        </template>
        <template v-else-if="column.dataIndex === 'editTime'">
          {{ dayjs(record.editTime).format('YYYY-MM-DD HH:mm:ss') }}
        </template>
        <template v-else-if="column.dataIndex === 'reviewTime'">
          {{ record.reviewTime ? dayjs(record.reviewTime).format('YYYY-MM-DD HH:mm:ss') : '' }}
        </template>
        <template v-if="column.dataIndex === 'userName'">
          {{ record.user.userName }}
        </template>
        <template v-if="column.dataIndex === 'reviewMessage'">
          {{ record.reviewMessage }}
        </template>
        <template v-else-if="column.key === 'action'">
          <a-space>
            <a-button type="primary" @click="showReviewModal(record)">审阅</a-button>
          </a-space>
        </template>
      </template>
    </a-table>

    <!-- 审阅弹窗 -->
    <a-modal
      v-model:visible="reviewModalVisible"
      title="笔记审阅"
      width="800px"
      :footer="null"
      :destroyOnClose="true"
    >
      <div class="review-content" v-if="currentNote">
        <h2 class="note-title">{{ currentNote.title }}</h2>
        <div class="user-info">
          <a-avatar :size="40" :src="currentNote.user?.userAvatar || '/avatar.png'" />
          <div class="user-meta">
            <div class="username">{{ currentNote.user?.userName }}</div>
            <div class="edit-time">
              {{ dayjs(currentNote.editTime).format('YYYY-MM-DD HH:mm:ss') }}
            </div>
          </div>
        </div>
        <!--  笔记封面 -->
        <div class="cover-image" v-if="currentNote.cover">
          <div class="cover-label">笔记封面：</div>
          <img :src="currentNote.cover" :alt="currentNote.title" />
        </div>

        <div class="category">
          所属分类：
          <a-tag color="green">{{ getCategoryName(currentNote.categoryId) }}</a-tag>
        </div>
        <div class="theme-selector">
          <span>选择主题：</span>
          <a-select v-model:value="currentTheme" style="width: 200px" @change="handleThemeChange">
            <a-select-option v-for="theme in themeList" :key="theme.name" :value="theme.name">
              {{ theme.name }}
            </a-select-option>
          </a-select>
        </div>
        <div class="content-preview">
          <Viewer :value="currentNote.content || ''" :plugins="plugins" />
        </div>
        <div class="tags">
          <span class="tag-label">标签：</span>
          <a-tag v-for="tag in currentNote.tagList" :key="tag.id" class="tag-item">
            {{ tag.tagName }}
          </a-tag>
        </div>
        <div class="review-actions">
          <a-space>
            <a-button type="primary" @click="showApproveConfirm">通过</a-button>
            <a-button danger @click="showRejectModal">拒绝</a-button>
          </a-space>
        </div>
      </div>
    </a-modal>

    <!-- 拒绝原因输入弹窗 -->
    <a-modal
      v-model:visible="rejectModalVisible"
      title="拒绝原因"
      @ok="handleReject"
      @cancel="rejectModalVisible = false"
      okText="确认"
      cancelText="取消"
      :zIndex="1001"
    >
      <a-textarea
        v-model:value="rejectReason"
        placeholder="请输入拒绝原因"
        :rows="4"
        :maxlength="200"
        show-count
      />
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { computed, createVNode, onMounted, reactive, ref, watch } from 'vue'
import { message, Modal } from 'ant-design-vue'
import dayjs from 'dayjs'
import {
  deleteNoteUsingPost,
  getNoteVoByIdUsingGet,
  listNoteTagsCategoryUsingGet,
  listPublicReviewingNotesByPageUsingPost,
  updateNoteUsingPost,
} from '@/api/notesController'
import { listUserVoByPageUsingPost } from '@/api/userController'
import { Viewer } from '@bytemd/vue-next'
import gfm from '@bytemd/plugin-gfm'
import highlight from '@bytemd/plugin-highlight'
import 'bytemd/dist/index.css'
import theme from 'bytemd-plugin-theme'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
import { currentTheme, handleThemeChange, themeList } from '@/utils/themeManager'
import mediumZoom from '@bytemd/plugin-medium-zoom'
import gemoji from '@bytemd/plugin-gemoji'
import footnotes from '@bytemd/plugin-footnotes'
import frontmatter from '@bytemd/plugin-frontmatter'
import breaks from '@bytemd/plugin-breaks'
import highlightssr from '@bytemd/plugin-highlight-ssr'

// ByteMD 插件
const plugins = [
  gfm(),
  highlight(),
  highlightssr(),
  breaks(),
  frontmatter(),
  footnotes(),
  gemoji(),
  theme(),
  mediumZoom(),
]

// 监听主题变化
watch(currentTheme, (newTheme) => {
  handleThemeChange(newTheme)
})

// 初始化主题
onMounted(() => {
  handleThemeChange(currentTheme.value)
})

// 用户列表
const userList = ref<API.UserVO[]>([])

// 获取用户列表
const fetchUsers = async () => {
  const res = await listUserVoByPageUsingPost({
    pageSize: 20, // 获取足够多的用户
    current: 1,
  })
  if (res.data.code === 0 && res.data.data) {
    userList.value = res.data.data.records ?? []
  } else {
    message.error('获取用户列表失败，' + res.data.message)
  }
}

// 获取用户名称
const getUserName = (userId: number) => {
  const user = userList.value.find((u) => u.id === userId)
  return user ? user.userName : ' '
}

// 修改 columns 定义
const columns = [
  {
    title: '笔记id',
    dataIndex: 'id',
    width: 100,
    ellipsis: true,
  },
  {
    title: '标题',
    dataIndex: 'title',
    width: 120, // 至少6个汉字宽度
    ellipsis: true,
    align: 'center',
  },
  {
    title: '类型',
    dataIndex: 'categoryId',
    width: 80, // 至少4个汉字宽度
    ellipsis: true,
    align: 'center',
    customRender: ({ text }) => getCategoryName(text),
  },
  {
    title: '标签',
    dataIndex: 'tagList',
    width: 120,
    ellipsis: true,
    align: 'center',
  },
  {
    title: '用户id',
    dataIndex: 'userId',
    width: 100,
    ellipsis: true,
    align: 'center',
  },
  {
    title: '用户名',
    dataIndex: 'userName',
    width: 100,
    ellipsis: true,
    align: 'center',
  },
  {
    title: '创建时间',
    dataIndex: 'createTime',
    width: 120,
    align: 'center',
  },
  {
    title: '编辑时间',
    dataIndex: 'editTime',
    width: 120,
    align: 'center',
  },
  {
    title: '审核人',
    dataIndex: 'reviewerId',
    width: 72,
    align: 'center',
    customRender: ({ text }) => getUserName(text),
  },
  {
    title: '审核状态',
    dataIndex: 'reviewStatus',
    width: 90,
    align: 'center',
    ellipsis: true,
    customRender: ({ text }) => {
      const statusMap = {
        0: '无需审核',
        1: '审核中',
        2: '已通过',
        3: '已拒绝',
      }
      return statusMap[text] || '未知状态'
    },
  },
  {
    title: '审核信息',
    dataIndex: 'reviewMessage',
    width: 160,
    align: 'center',
  },
  {
    title: '审核时间',
    dataIndex: 'reviewTime',
    width: 120,
    align: 'center',
  },
  {
    title: '操作',
    key: 'action',
    width: 80,
    fixed: 'right',
    align: 'center',
  },
]

// 数据
const dataList = ref([])
const total = ref(0)

// 搜索条件
const searchParams = reactive<API.NotesQueryRequest>({
  current: 1,
  pageSize: 10,
  sortField: 'create_time',
  sortOrder: 'descend',
  visibility: 1,
  reviewStatus: 1,
})

// 分页参数
const pagination = computed(() => {
  return {
    current: searchParams.current ?? 1,
    pageSize: searchParams.pageSize ?? 10,
    total: total.value,
    showSizeChanger: true,
    showTotal: (total) => `共 ${total} 条`,
  }
})

// 分类列表
const categoryList = ref<API.Categories[]>([])

// 获取分类列表
const fetchCategories = async () => {
  const res = await listNoteTagsCategoryUsingGet()
  if (res.data.code === 0 && res.data.data) {
    categoryList.value = res.data.data.categoriesList ?? []
  } else {
    message.error('获取分类列表失败，' + res.data.message)
  }
}

// 获取分类名称
const getCategoryName = (categoryId: number) => {
  const category = categoryList.value.find((cat) => cat.id === categoryId)
  return category ? category.categoryName : '默认'
}

// 获取数据
const fetchData = async () => {
  const res = await listPublicReviewingNotesByPageUsingPost({
    ...searchParams,
  })
  if (res.data.data) {
    dataList.value = res.data.data.records ?? []
    // console.log('管理数据' + dataList.value)
    total.value = res.data.data.total ?? 0
  } else {
    message.error('获取数据失败，' + res.data.message)
  }
}

// 页面加载时请求一次
onMounted(() => {
  fetchCategories()
  fetchUsers()
  fetchData()
})

// 获取数据
const doSearch = () => {
  // 重置搜索条件
  searchParams.current = 1
  fetchData()
}

// 表格变化处理
const doTableChange = (page: any) => {
  searchParams.current = page.current
  searchParams.pageSize = page.pageSize
  fetchData()
}

// 删除数据
const doDelete = async (id: string) => {
  if (!id) {
    return
  }
  const res = await deleteNoteUsingPost({ id })
  if (res.data.code === 0) {
    message.success('删除成功')
    // 刷新数据
    fetchData()
  } else {
    message.error('删除失败')
  }
}

// 审阅弹窗相关
const reviewModalVisible = ref(false)
const currentNote = ref<API.NotesVO | null>(null)

// 显示审阅弹窗
const showReviewModal = async (note: API.NotesVO) => {
  // 获取完整笔记信息
  const res = await getNoteVoByIdUsingGet({ id: note.id })
  if (res.data.code === 0 && res.data.data) {
    currentNote.value = res.data.data
    reviewModalVisible.value = true
  } else {
    message.error('获取笔记详情失败，' + res.data.message)
  }
}

// 审核相关
const rejectModalVisible = ref(false)
const rejectReason = ref('')

// 显示通过确认框
const showApproveConfirm = () => {
  Modal.confirm({
    title: '确认通过',
    icon: createVNode(ExclamationCircleOutlined),
    content: '确定要通过这篇笔记吗？',
    okText: '确认',
    cancelText: '取消',
    zIndex: 1000,
    async onOk() {
      await handleApprove()
    },
  })
}

// 处理通过
const handleApprove = async () => {
  if (!currentNote.value) return

  try {
    const res = await updateNoteUsingPost({
      ...currentNote.value,
      reviewStatus: 2,
    })

    if (res.data.code === 0) {
      message.success('审核通过成功')
      reviewModalVisible.value = false
      fetchData() // 刷新列表
    } else {
      message.error('操作失败：' + res.data.message)
    }
  } catch (error: any) {
    message.error('操作失败：' + error.message)
  }
}

// 显示拒绝弹窗
const showRejectModal = () => {
  rejectReason.value = ''
  rejectModalVisible.value = true
}

// 处理拒绝
const handleReject = async () => {
  if (!currentNote.value || !rejectReason.value.trim()) {
    message.warning('请输入拒绝原因')
    return
  }

  try {
    const res = await updateNoteUsingPost({
      ...currentNote.value,
      reviewStatus: 3,
      reviewMessage: rejectReason.value.trim(),
    })

    if (res.data.code === 0) {
      message.success('已拒绝该笔记')
      rejectModalVisible.value = false
      reviewModalVisible.value = false
      fetchData() // 刷新列表
    } else {
      message.error('操作失败：' + res.data.message)
    }
  } catch (error: any) {
    message.error('操作失败：' + error.message)
  }
}
</script>

<style scoped>
.review-content {
  .note-title {
    margin-bottom: 20px;
    text-align: center;
    font-size: 24px;
  }

  .user-info {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;

    .user-meta {
      display: flex;
      flex-direction: column;
      gap: 4px;

      .username {
        font-weight: 500;
      }

      .edit-time {
        color: rgba(0, 0, 0, 0.45);
        font-size: 12px;
      }
    }
  }

  .cover-image {
    margin: 16px 0;
    text-align: center;

    .cover-label {
      text-align: left;
      margin-bottom: 8px;
      color: rgba(0, 0, 0, 0.65);
      font-size: 14px;
    }

    img {
      max-width: 100%;
      max-height: 300px;
      object-fit: contain;
      border-radius: 8px;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    }
  }

  .category {
    margin-bottom: 16px;
    color: rgba(0, 0, 0, 0.65);
  }

  .theme-selector {
    margin: 16px 0;
    display: flex;
    align-items: center;
    gap: 8px;

    span {
      color: rgba(0, 0, 0, 0.65);
    }
  }

  .content-preview {
    margin: 24px 0;
    border: 1px solid #f0f0f0;
    border-radius: 8px;
    padding: 24px;
    background: #ffffff;
  }

  .tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;

    .tag-label {
      color: rgba(0, 0, 0, 0.65);
    }

    .tag-item {
      border-radius: 2px;
    }
  }

  .review-actions {
    margin-top: 24px;
    display: flex;
    justify-content: center;
  }
}

.tags-wrapper {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  .tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    justify-content: center;
    align-items: center;
    width: 100%;
    min-height: 32px;

    .tag-item {
      margin: 2px;
    }
  }
}
</style>
